home *** CD-ROM | disk | FTP | other *** search
- Path: dawn.mmm.com!news
- From: kjhopps@mmm.com (Kevin J Hopps)
- Newsgroups: comp.lang.c++
- Subject: Re: Copy constructing an already default constructed object
- Date: 26 Jan 1996 23:08:13 GMT
- Organization: 3M - St. Paul, MN 55144-1000 US
- Message-ID: <4ebmst$7cl@dawn.mmm.com>
- References: <4e906b$stk@elaine32.Stanford.EDU> <4eal0n$hgq@dawn.mmm.com> <3108ef14.340699@nntp>
- Reply-To: kjhopps@mmm.com
- X-Newsreader: TIN [version 1.2 PL2]
-
- brien oberstein (brien@leland.stanford.edu) wrote:
- > On 26 Jan 1996 13:29:59 GMT, kjhopps@mmm.com (Kevin J Hopps) wrote:
-
- [ example elided ]
-
- > >First, you have to decide for yourself what the copy semantics of
- > >your class are -- deep or shallow. Regardless of what you decide,
- > >I think that the copy constructor and the assignment operator
- > >should produce identical results. Frequently one is written in
- > >terms of the other. Ultimately they must do an exhaustive copy
- > >of each data member. Using memcpy as above can overwrite
- > >compiler-generated data within the object and can have unpredictable
- > >results.
- > <snip>
-
- > What compiler generated data? The vtable pointer? What if I'm not
- > using virtual functions?
-
- If you're using virtual functions memcpy is definitely bad. If you're
- not, I don't know whether it is guaranteed to work or not.
-
- > Ok. Lemme give a better example of the actual problem I'm having.
- > The object I have has other objects within it (which allocate
- > dynamically), but no pointers are contained _directly_ in its class.
-
- If you do not specify a copy constructor, one will be provided for
- you. By default, it does a *memberwise* (not bitwise) copy.
-
- > class A{
- > public:
- > A();
- > A(const A&);
- > A(char *);
-
- > private:
- > B b0, b1;
- > };
-
- For this class, a memberwise copy would be sufficient, assuming
- that copying B's does what you want. (If B is a class, it must
- either have a copy constructor, or perform correctly with memberwise
- copying. If B is a pointer, you might have problems.) So, you
- don't need to specify a copy constructor for A. (FWIW, I always
- do anyway, for completeness and to show the reader that I haven't
- forgotten about copying.)
-
- > class B{
- > public:
- > B();
- > B(const B&);
- > B(char *);
-
- > private:
- > char *p;
- > }
-
- If you want "deep copy" semantics for B, you must provide a
- copy constructor here unless you want copied B's to share the
- same pointers.
-
- > So my copy constructor for A is easy:
- > A::A(const A& other) : b0(other.b0), b1(other.b1) { }
-
- > Now how do you do the copy? Do you have to
- > overload = for all the contained operators too?
- > ie,
-
- The rule for the assignment operator is the same as the
- rule for the copy constructor. If memberwise assignment
- works, then you don't need to provide an assignment
- operator.
-
- I'm not sure what you mean by "contained operators." If
- you are asking whether you need to overload operator= for
- member objects, the answer is the same -- you need to
- overload operator= if memberwise assignment is not what
- you want.
-
- > A::operator =(const A& other)
- > {
- > b0 = other.b0 ;
- > b1 = other.b1;
- > }
-
- Be sure to check for (this != &other).
-
- > To me this seems like a major pain in the butt. All I really
- > want to do is have the copy constructor invoked on the piece that
- > piece of memory. Why can't this be done?
-
- Personally, I find the assignment operator almost exactly as
- "painful" to write as the copy constructor. But if for some
- reason it is more painful to initialize objects in operator=
- than in the copy constructor, you could write operator= this way:
- void A::operator=(const A& rhs)
- {
- if (this != &rhs) {
- this->~A();
- new (this) A(rhs);
- }
- }
-
- But for two members, it's the same number of lines anyway :-)
- --
- Kevin J. Hopps e-mail: kjhopps@mmm.com
- 3M Company phone: (612) 737-4643
- 3M Center, Bldg. 235-2D-57 fax: (612) 737-2700
- St. Paul, MN 55144-1000 Opinions are my own. I don't speak for 3M.
- But 3M speaks for me -- I did not write the following line:
-
- Opinions expressed herein are my own and may not represent those of 3M.
-